//It's a head file about some basic data types to different compilers
//it's in clang++ 

//a data type covered a point-long data
#ifndef COMPILE_H
#define COMPILE_H
//#define _ptlong  __ptlong
//#define _hfptlong unsigned short
//#define __KERNEL_PANIC(num)  
//#define PAGE_SIZE_OFFSET  12
#include <compile_base.h>

#define __KERNEL_PANIC(num)  

template<typename A,typename B>
inline A __force_cast(const A to,const B& from)
{
  A ret;
  char* a = (char*)&ret;
  char* b = (char*)&from;
  for(int i =0 ; i < sizeof(A) ; i++)
    a[i] = b[i];
  return ret;
}

#define type_as_argv(x) ([]()->x{x a;return a;}())
#define _force_cast(x,y) force_cast(type_as_argv(x),y)

template<bool k>
struct __convert{};

template<>
struct __convert<true>
{
template<typename T>
static inline __ptlong fun(T x){return x;}
};

template<>
struct __convert<false>
{
template<typename T>
static inline __ptlong fun(T x){return __force__cast(type_as_argv(__ptlong),x);}
};

struct _ptlong 
{
__ptlong data;
constexpr explicit _ptlong(const _ptlong& x):data(x.data){}

constexpr _ptlong()noexcept:data(0){} 
constexpr _ptlong(const __ptlong x)noexcept:data(x){}
//explicit _ptlong(const _longest x):data(__force_cast(data,x)){}
inline volatile const _ptlong(volatile const _ptlong& x){data = x.data;}



inline const volatile operator __ptlong()const volatile {return data;}
inline const volatile operator __ptlong()volatile {return data;}
inline const operator __ptlong()const {return data;}
inline const operator __ptlong() {return data;}



template<typename T>
_ptlong(T* x):data(__force_cast(type_as_argv(_ptlong),x)){}

inline volatile const _ptlong& operator=(volatile const _ptlong& x)volatile noexcept {data = x.data;return x;}
inline const _ptlong& operator=(const _ptlong& x) noexcept {data = x.data;return x;}

inline volatile const _ptlong& operator=(volatile const _ptlong&& x)volatile noexcept {data = x.data;return *this;}
inline const _ptlong& operator=(const _ptlong&& x) noexcept {data = x.data;return *this;}

//inline volatile const _ptlong& operator=(volatile const __ptlong x)volatile noexcept {data = x;return *this;}
//inline const _ptlong& operator=(const __ptlong x) noexcept {data = x;return *this;}


template<typename T>
inline volatile const _ptlong& operator=(volatile const T* x)volatile noexcept{(data = __force_cast(type_as_argv(_ptlong),x));return *this;}
template<typename T>
inline const _ptlong& operator=(const T* x) noexcept{(data = __force_cast(type_as_argv(_ptlong),x));return *this;}

/*
inline explicit volatile operator _ptlong*()const volatile {return __force_cast(type_as_argv(_ptlong*),data);}
inline explicit volatile operator _ptlong*()volatile {return __force_cast(type_as_argv(_ptlong*),data);}
inline explicit operator _ptlong*()const  {return __force_cast(type_as_argv(_ptlong*),data);}
inline explicit operator _ptlong*() {return __force_cast(type_as_argv(_ptlong*),data);}
*/
template<typename T>
inline explicit volatile operator T*()const volatile {return __force_cast(type_as_argv(T*),data);}
template<typename T>
inline explicit volatile operator T*()volatile {return __force_cast(type_as_argv(T*),data);}
template<typename T>
inline explicit operator T*()const  {return __force_cast(type_as_argv(T*),data);}
template<typename T>
inline explicit operator T*() {return __force_cast(type_as_argv(T*),data);}

template<typename T>
inline const operator T()const volatile= delete;
template<typename T>
inline const operator T()const = delete;
template<typename T>
inline const operator T()volatile = delete;
template<typename T>
inline const operator T() = delete;

template<typename T>
inline _ptlong operator+=(const T x){return (_ptlong)(data += (__ptlong)x);}
template<typename T>
inline volatile _ptlong operator+=(const T x)volatile{return (_ptlong)(data += (__ptlong)x);}
template<typename T>
inline _ptlong operator-=(const T x){return (_ptlong)(data -= (__ptlong)x);}
template<typename T>
inline volatile _ptlong operator-=(const T x)volatile{return (_ptlong)(data -= (__ptlong)x);}
template<typename T>
inline _ptlong operator&=(const T x){return (_ptlong)(data &= (__ptlong)x);}
template<typename T>
inline volatile _ptlong operator&=(const T x)volatile{return (_ptlong)(data &= (__ptlong)x);}
template<typename T>
inline _ptlong operator|=(const T x){return (_ptlong)(data |= (__ptlong)x);}
template<typename T>
inline volatile _ptlong operator|=(const T x)volatile{return (_ptlong)(data |= (__ptlong)x);}

inline _ptlong operator++(int){_ptlong& _this = *this;++data;return _this;}
inline volatile _ptlong operator++(int)volatile{volatile _ptlong& _this = *this;++data;return _this;}
inline _ptlong operator++(){return (++data,*this);}
inline volatile _ptlong operator++()volatile{return (++data,*this);}
//inline _ptlong operator=(_ptlong* x){return force_cast(type_as_argv(_ptlong),x);}
};

#define PAGE_SIZE (1 << PAGE_SIZE_OFFSET)

#endif
